LshProjection

局部敏感哈希(LSH)投影。对每个哈希组,用 bits_per_hash 个种子对输入特征做加权哈希评分, 按评分符号拼出一组 int32 哈希签名。

设哈希组数为 \(G\),即 hash_group_num;每组位数为 \(B\),即 bits_per_hash; 特征维数为 \(F\),即 feature_numhash_seed 长度为 \(G \cdot B\)feature / weight 长度为 \(F\)output 长度为 \(G\)

对组下标 \(i = 0,\ldots,G-1\)

\[\begin{split}\begin{aligned} \mathrm{hash\_sign} &\leftarrow 0 \\ \text{对 } j = 0,\ldots,B-1\text{:}\quad s &\leftarrow \mathrm{hash\_seed}[i\cdot B + j] \\ \mathrm{score} &\leftarrow \sum_{k=0}^{F-1} w_k \cdot \mathrm{float}\!\big(\mathrm{FNV1a}_{32}(s \Vert \mathrm{feature}[k])\big) \\ b &\leftarrow \begin{cases} 1, & \mathrm{score} > 0 \\ 0, & \text{otherwise} \end{cases} \\ \mathrm{hash\_sign} &\leftarrow (\mathrm{hash\_sign}\ll 1) \lor b \\ \mathrm{output}[i] &\leftarrow \mathrm{hash\_sign} \end{aligned}\end{split}\]

其中 \(s \Vert \mathrm{feature}[k]\) 表示将 float 种子与 int32 特征按字节拼接 共 8 字节后做 FNV1a-32。若 weight == NULL,则 \(w_k = 1\);否则 \(w_k = \mathrm{weight}[k]\)

输入:
  • hash_seed - 哈希种子数组,类型 float,长度 hash_group_num * bits_per_hash

  • feature - 特征向量,类型 int32,长度 feature_num

  • weight - 权重向量,长度 feature_num;类型随接口前缀变化;可为 NULL

  • hash_group_num - 哈希组数 \(G\),即输出长度

  • bits_per_hash - 每组有效位数 \(B\),通常不超过 32

  • feature_num - 特征维数 \(F\)

  • core_mask - 核掩码(仅共享存储版本使用)

输出:
  • output - 哈希签名数组,类型 int32,长度 hash_group_num

支持平台:

FT78NE MT7004

备注

  • 特征 feature 与输出 output 固定为 int32

  • FT78NE 权重类型:int8、int16、int32、fp32、fp64

  • MT7004 权重类型:int16、int32、fp16、fp32

  • 内部哈希为 FNV1a-32;weightNULL 时不加权重

共享存储版本:

void i8_lsh_projection_s(const float *hash_seed, const int32_t *feature, const int8_t *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num, int core_mask)
void i16_lsh_projection_s(const float *hash_seed, const int32_t *feature, const int16_t *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num, int core_mask)
void i32_lsh_projection_s(const float *hash_seed, const int32_t *feature, const int32_t *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num, int core_mask)
void hp_lsh_projection_s(const float *hash_seed, const int32_t *feature, const float16 *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num, int core_mask)
void fp_lsh_projection_s(const float *hash_seed, const int32_t *feature, const float *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num, int core_mask)
void dp_lsh_projection_s(const float *hash_seed, const int32_t *feature, const double *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num, int core_mask)

C调用示例:

 1// MT7004 示例(共享存储多核,DDR 地址)
 2void TestLshProjectionSMCFp32(int hash_group_num, int core_mask) {
 3    int core_id = get_core_id();
 4    int logic_core_id = GetLogicCoreId(core_mask, core_id);
 5    int core_num = GetCoreNum(core_mask);
 6    float *hash_seed = (float *)0x88000000;
 7    int32_t *feature = (int32_t *)0x8A000000;
 8    float *weight = (float *)0x8A001000;
 9    int32_t *output = (int32_t *)0x90000000;
10    int bits_per_hash = 4;
11    int feature_num = 5;
12    sys_bar(0, core_num);
13    fp_lsh_projection_s(hash_seed, feature, weight, output, hash_group_num, bits_per_hash, feature_num, core_mask);
14}
15
16void main() {
17    int core_mask = 0b1111;
18    TestLshProjectionSMCFp32(256, core_mask);
19}

私有存储版本:

void i8_lsh_projection_p(const float *hash_seed, const int32_t *feature, const int8_t *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num)
void i16_lsh_projection_p(const float *hash_seed, const int32_t *feature, const int16_t *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num)
void i32_lsh_projection_p(const float *hash_seed, const int32_t *feature, const int32_t *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num)
void hp_lsh_projection_p(const float *hash_seed, const int32_t *feature, const float16 *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num)
void fp_lsh_projection_p(const float *hash_seed, const int32_t *feature, const float *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num)
void dp_lsh_projection_p(const float *hash_seed, const int32_t *feature, const double *weight, int32_t *output, int hash_group_num, int bits_per_hash, int feature_num)

C调用示例:

 1// MT7004 示例(私有存储单核,AM 地址)
 2void TestLshProjectionAMFp32(int hash_group_num) {
 3    float *hash_seed = (float *)0x10000000;
 4    int32_t *feature = (int32_t *)0x10020000;
 5    float *weight = (float *)0x10030000;
 6    int32_t *output = (int32_t *)0x10040000;
 7    int bits_per_hash = 4;
 8    int feature_num = 5;
 9    fp_lsh_projection_p(hash_seed, feature, weight, output, hash_group_num, bits_per_hash, feature_num);
10}
11
12void main() {
13    TestLshProjectionAMFp32(256);
14}